__author__ = 'JackSong'
import sys
import signal
import logging
import os.path
import tornadis
import tornado.web
import tornado.ioloop
import tornado.options
import logging.handlers
import tornado.httpserver

from config import Conf
from urls import handlers
from tornado.options import define
from tornado.options import options
from tornado.gen import Return, coroutine
from middleware.authMiddleware import SignatureAuthMiddleware, TimeAuthMiddleware

reload(sys)
sys.setdefaultencoding('utf-8')

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
settings = dict(
    template_path=os.path.join(os.path.dirname(__file__), "templates"),
    static_path=os.path.join(os.path.dirname(__file__), "static"),

)
CONF = Conf(BASE_DIR + "/gateway.conf")


class Application(tornado.web.Application):
    CONNECTION_POOL = tornadis.ClientPool(max_size=500,
                                          client_timeout=60,
                                          db=CONF.redis.db,
                                          **dict(host=CONF.redis.host, port=int(CONF.redis.port)))

    def __init__(self):
        tornado.web.Application.__init__(self, handlers, **settings)

        self.middlewares = (TimeAuthMiddleware(), SignatureAuthMiddleware(),)

    @coroutine
    def _get_redis(self, *args):
        with (yield self.CONNECTION_POOL.connected_client()) as client:
            if not isinstance(client, tornadis.TornadisException):
                res = yield client.call(*args)
                if not isinstance(res, tornadis.TornadisException):
                    raise Return(res)
                else:
                    raise Return('')


def init_config(conf):
    define('port', default=conf.tornado.port, type=int, help='server listening port')
    define("debug", default=conf.tornado.debug, help="Debug Mode", type=bool)
    define("log_to_stderr", default=conf.tornado.log_to_stderr, help="Debug Mode", type=str)
    define("log_file_max_size", default=conf.tornado.log_file_max_size, help="Debug Mode", type=int)
    define("log_file_num_backups", default=conf.tornado.log_file_num_backups, help="Debug Mode", type=bool)
    define("log_file_prefix", default=conf.tornado.log_file_prefix, help="Debug Mode", type=str)
    define("ceph", default=conf.tornado.ceph, help="ceph config", type=str)
    define("ceph_block_size", default=int(conf.tornado.ceph_block_size), help="ceph block size", type=int)
    define("ceph_key", default=conf.tornado.ceph_key, help="ceph key config", type=str)
    define("ceph_api", default=conf.tornado.ceph_api, help="ceph api root url", type=str)
    define("ceph_source_pool", default=conf.tornado.ceph_source_pool, help="ceph source pool", type=str)
    define("database", default=conf.databases.connect, help="database connect", type=str)
    define("secret_key", default=conf.siganture.secret_key, help="secret key", type=str)
    define("access_key", default=conf.siganture.access_key, help="access key", type=str)
    define("performance_ruleset", default=conf.performance.crush_ruleset, help="performance ruleset", type=str)
    define("performance_size", default=conf.performance.size, help="performance size", type=str)
    define("normal_size", default=conf.normal.size, help="normal size", type=str)
    define("normal_ruleset", default=conf.normal.size, help="normal ruleset", type=str)
    define("pid_file", default=conf.tornado.pid_file, help="normal ruleset", type=str)
    define("high_performance_ruleset", default=conf.high_performance.ruleset, help="high performance ruleset", type=str)
    define("high_performance_size", default=conf.high_performance.size, help="high performance size", type=str)


def main():
    http_server = tornado.httpserver.HTTPServer(Application())
    http_server.listen(options.port)
    logger = logging.getLogger()
    timelog = logging.handlers.TimedRotatingFileHandler(options.log_file_prefix)
    logger.addHandler(timelog)
    print('Server Starting on port %s' % (options.port,))
    with open(options.pid_file, 'wr+') as file:
        file.write(str(os.getpid()))
    try:
        tornado.ioloop.IOLoop.instance().start()
    except KeyboardInterrupt:
        os.remove(options.pid_file)


def migrate():
    from db import init_db
    init_db()


def stop():
    try:
        print options.pid_file
        with open(options.pid_file, 'r+') as file:
            pid = file.readline()
            if pid:
                os.kill(int(pid), signal.SIGKILL)
                os.remove(options.pid_file)
    except IOError:
        print 'not find pid file'


def status():
    try:
        with open(options.pid_file, 'r+') as file:
            pid = file.readline()
            if pid:
                print 'pid is %s' % (pid,)
    except IOError:
        print 'not find pid file'

if __name__ == "__main__":
    argv = sys.argv.pop(1)
    init_config(CONF)
    options.parse_command_line()
    if argv == 'migrate':
        migrate()
    elif argv == 'start':
        main()
    elif argv == 'stop':
        stop()
    elif argv == 'restart':
        stop()
        main()
    elif argv == "status":
        status()
